Kubernetes for Beginners
↑のワークショップをやりつつ取ったメモ。ほとんど和訳っぽいのは目をつぶってください。
一定時間でnodeが終了するのか、しばしば停止する。リロードすると別のホストに接続できる。
左側の手順をもとに右側のターミナルにコマンドを書く形式。ターミナルが複数あるのはnodeが複数ある前提。Docker IDかGithub のアカウントがあれば始められる。ターミナルはCentosベース。色がついているコマンドラインはクリックするだけで自動でターミナルに入力される。
クラスターの開始
code:shell
kubeadm init --apiserver-advertise-address $(hostname -i)
--apiserver-advertise-address は kubernetes API serverがどのIPアドレスで待ち受けるかを示すための引数
hostname -iはホストのIPアドレスを返す
実行してしばらく立つと下記のようなクラスタに参加するためのコマンドが返される
code:shell
kubeadm join --token SOMETOKEN SOMEIPADDRESS --discovery-token-ca-cert-hash SOMESHAHASH
--token はクラスタに参加するためのトークン
--discovery-token-ca-cert-hash はルートCA証明書を検証するためのハッシュ
表示されたものをそのまま実行する
その後、次のコマンドを実行する。
code:shell
kubectl apply -n kube-system -f \
-f は指定するファイル
-n はnamespaceかな?helpを叩いてもわからなかった
これでクラスタのネットワークが初期化完了する
このワークショップで動かすアプリケーション
worker はrngにランダムなバイト生成を要求する
worker は hasher に取得したバイトを送信する
上記の処理を無限ループで実行
workerはredis にどれだけループし終わったか記録する
webuiはredisの情報をもとにどれだけDockerCoinを掘れるか返す
docker-compose up で立ち上げられる。node1のターミナルで立ち上げたなら8000番から見られるように設定されている。
Kubernetesのコンセプト
k8sはコンテナ管理システム
クラスタ上にコンテナアプリを立ち上げ管理する
K8sに期待すること
atseashop/api:v1.3のイメージを5コンテナ起動したい
これらのコンテナの前に internal なロードバランサを置きたい
atseashop/webfront:v1.3を使って10コンテナ起動したい
これらのコンテナの前に public なロードバランサを起きたい
クリスマスシーズン等でリクエストがスパイクしたらクラスタを拡大させてコンテナを追加したい
新しいリリースをする時、新しいイメージへ差し替えている間、リクエストを処理させたい
k8s がほかに提供する機能
基本的なオートスケール
Blue/Greenデプロイ、カナリアデプロイ
サービスの長期実行/バッチ実行
クラスタ内のサービスが増えすぎた場合は優先度の低いJobは停止する
DBなど状態を持つサービスの実行
リソースごとにだれが実行できるかをきめ細かく定義できる
サードパーティ製サービスと統合できる
複雑なタスクを自動化できる
K8sのアーキテクチャ
マスターとは?
サービス群の司令塔
APIサーバ
スケジューラやコントローラ管理などのコアなサービスを実行
etcd(K8sのデータベースKVS)
host内で実行されることもあればコンテナで実行されることもある。
etcdは複数のマシンで実行されることもあれば同じマシンで実行されることもある
1つ以上のマスターがあればOK.高可用性のために複数運用も可
ノードとは?
ノードはアプリケーションコンテナ等を実行する
Dockerのようなコンテナエンジン
kubelet(ノードエージェント)
kube-proxy(ネットワークコンポーネント)
ミニオンと呼ばれることもある
K8s のリソース
リソースと呼ばれるたくさんのオブジェクトをk8sのAPIは定義している
よく使うリソースは
node: クラスタに存在するマシン(物理マシン、仮想環境区別せず)
pod: node上で一緒に動かすコンテナのグループ
service: コンテナを接続できる安定したネットワークのエンドポイント
namespace: 独立したグループ
secret: センシティブなデータをコンテナに受け渡す
他にもある。 kubectl api-resources すると全リストを見られる
宣言的 vs 命令的
k8sは宣言的であることを重んじる
宣言的とは: 1杯の紅茶がほしい
命令的とは: 水を沸騰させる。急須に入れる。紅茶葉を入れる。浸してしばらく待つ。カップに入れる
宣言的のほうがぱっと見簡単にみえる
...紅茶の入れ方を知るまでは
実のところ宣言的とは:
カップに入っていて十分に紅茶葉から抽出された1杯の紅茶がほしい
抽出方法は熱湯のなかに紅茶葉を数分浸すこと
熱湯とはコンロの上に水を入れたコンテナを置くことで得られる
コンテナであれば僕らも多少はわかる。やってみよう?
宣言的 vs 命令的のまとめ
命令的:
簡単
処理が中断されると最初から再スタート
命令的
処理が中断される(もしくは道半ばで終わらせると)と、何が足らないか自明になる
システムを監視することが必要
... ほしいものといまあるものの差分を計算する必要がある
k8sにおける宣言的 vs 命令的
k8sで作成するものはすべて spec から作成される
specはYAMLファイルで定義される。詳細は後ほど
spec にはあるべき状態を定義する
K8sは現在の状態とspecに合わせていく (技術的にはいくつかのコントローラを使う)
リソースを変更したいときは spec を変更する
K8sは リソースを spec に収束させる
K8sのネットワークモデル
TL,DR:
クラスタ(nodeとpod)は一つの大きくフラットなIPネットワークを構成する
もう少し詳しく書くと
すべてのnodeはNATを介さずにお互い通信できる
すべてのpodはNATを介さずにお互い通信できる
podとnodeはNATを介さずにお互い通信できる
podは各々IPアドレスを持つ(NATなしで)
k8sは特定の実装を押し付けることはない
メリット
すべてのものが各々通信可能
アドレス変換が不要
ポート変換が不要
新たなプロトコルも不要
Podは同一のIPアドレスを保ったまま他のnodeに移動できない
IPアドレスはnodeをまたいでポータブルである必要はない(そうすることは可能: nodeごとにサブネットを作成し、シンプルな)
不十分なポイント
すべてのものが各々通信可能
セキュリティが必要な場合、ネットワークポリシーの追加が必要
ネットワークの実装は必要とするネットワークポリシーをサポートするものでなければならない
確かにk8s用のネットワーク実装はたくさんある。(ドキュメントにも15個の実装が書かれている)
L3 ネットワークの設定が必要でもL4しかない(spec はUDPとTCPのみサポートし、ポートレンジや任意のIPパケットはサポートしない)
kube-proxyをコンテナやpodの接続を行うパスに配置できるが、特別高速というわけではない。(iptablesやproxyを使っているため)
実際のところ
nodeをのセットアップにはWeaveをよく使う
Weaveを押し付けるつもりはない。私達にはあっていると言うだけ
kube-proxyのパフォーマンスも心配するほどではない
下記に該当しなければ:
10G ネットワークインターフェースを充満させるほどの通信量
秒間100万パケット
通信量が多いVOIPやゲームプラットフォームでの実行
100万同期コネクション(こういう場合はカーネルチューニングが必要)
kubectlはじめの一歩
kubectl はk8sについて語る上で解説する必要があるただ一つのツール
kubectl はk8s APIで提供されるすべての機能が使えるCLIツール
設定ファイルを渡すには--kubeconfigフラグで渡す
直接--serverや--userを指定できる
kubectlはきゅーぶしーてぃーえる、きゅーぶかとる、きゅーぶかどる、きゅーぶこんとろーると呼ばれる
kubectl get
Nodeをkubectl getでみてみよう
クラスタ内で kubectl get node と打つ nodeは nodes, no とも表記できる
マシンリーダブルな出力をする
kubectl get -o wide
実行環境がDisk full になりがちなので一旦PEND